#include "gaussian.h"

Gaussian::Gaussian() {
    mu = 0;
    sigma2 = 1;
}

Gaussian::Gaussian(float average, float sigma) {
    mu = average;
    sigma2 = sigma;
}

void Gaussian::setMu(float average) {
    mu = average;
}

void Gaussian::setSigma2(float s) {
    sigma2 = s;
}

float Gaussian::getMu() {
    return mu;
}

float Gaussian::getSigma2() {
    return sigma2;
}

float Gaussian::evaluate(float x) {
    float coefficient;
    float exponential;
    // pi的书写形式是:M_PI
    coefficient = static_cast<float>(1.0 / sqrt(2.0 * M_PI * sigma2));
    exponential = static_cast<float>(exp(pow(-0.5 * (x - mu), 2) / sigma2));
    return coefficient * exponential;
}

Gaussian Gaussian::add(Gaussian other) {
    float new_mu = mu + other.getMu();
    float new_sigma2 = sigma2 + other.getSigma2();
    return Gaussian(new_mu, new_sigma2);
}

Gaussian Gaussian::mul(Gaussian other) {
    float denominstor = sigma2 + other.getSigma2();
    float numerator = mu * other.getSigma2() + sigma2 * other.getMu();
    float new_mu = numerator / denominstor;
    float new_sigma2 = 1.0 / ((1.0 / sigma2) + (1.0 / other.getSigma2()));
    return Gaussian(new_mu, new_sigma2);
}

void test_gaussian() {
    Gaussian my_gaussian(30.0, 100.0);
    Gaussian other_gaussian(10.0, 25.0);
    cout << "mu:" << my_gaussian.getMu() << endl;
    cout << "sigma2:" << my_gaussian.getSigma2() << endl;

    Gaussian result = my_gaussian.mul(other_gaussian);
    cout << "mul result mu:" << result.getMu()<<endl;
    cout << "mul result sigma2:" << result.getSigma2() << endl;


    Gaussian result1 = my_gaussian.add(other_gaussian);
    cout << "mul result1 mu:" << result1.getMu()<<endl;
    cout << "mul result1 sigma2:" << result1.getSigma2() << endl;


}
